package cc.rengu.redp.common.render;

import cc.rengu.redp.common.render.core.RenderService;
import cc.rengu.redp.common.render.core.RenderServiceImpl;
import cc.rengu.redp.common.utils.CamelUtil;
import cc.rengu.redp.common.utils.SpringContextUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 字段渲染工具类
 *
 * @Author xushitang
 */
@Slf4j
public class RenderUtil {

    private static RenderService renderService = SpringContextUtil.getBean(RenderServiceImpl.class);

    private final static String FIELD_NAME_EXTEND = "Render";

    /**
     * 对实体类进行渲染（仅支持get、set的String字段）
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T rendField(T t) {

        Field[] fields = t.getClass().getDeclaredFields();

        for (Field field : fields) {
            if (renderService.isRenderField(field.getName())) {
                try {
                    field.setAccessible(true);
                    String fieldName = field.getName();
                    Object obj = field.get(t);
                    //仅渲染String类型
                    if (obj instanceof String) {
                        String value = (String) obj;
                        String newValue = renderService.render(field.getName(), value, value);
                        String methodName = String.format("set%s%s", Character.toUpperCase(fieldName.charAt(0)), fieldName.substring(1));
                        Method setMethod = t.getClass().getMethod(methodName, String.class);
                        setMethod.setAccessible(true);
                        setMethod.invoke(t, newValue);
                    }
                } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                    log.error("field get value error, field name: {}, exception: {}", field.getName(), e.getMessage());
                }
            }
        }

        return t;
    }

    /**
     * JSONObject 字段渲染
     *
     * @param jsonObj
     * @return
     */
    public static JSONObject addRenderFieldToJson(JSONObject jsonObj) {
        JSONObject jsonFieldResult = new JSONObject();
        for (Map.Entry<String, Object> entry : jsonObj.entrySet()) {
            if (renderService.isRenderField(entry.getKey())) {
                if (entry.getValue() instanceof String && StringUtils.isNotBlank((String) entry.getValue())) {
                    String beforeRenderValue = (String) entry.getValue();
                    String result = renderService.render(entry.getKey(), beforeRenderValue, beforeRenderValue);
                    if (StringUtils.isNotBlank(result)) {
                        jsonFieldResult.put(getRenderName(entry.getKey()), result);
                    }
                }
            }
        }
        jsonObj.putAll(jsonFieldResult);
        return jsonObj;
    }

    /**
     * 组装描述字段
     * 	规则：原字段名称+FIELD_NAME_EXTEND
     * @param fieldName
     * @return
     */
    public static String getRenderName(String fieldName){
        return fieldName + FIELD_NAME_EXTEND;
    }
}
